#include "AdjacencyList.h"
#include "stdlib.h"
#include "logger.h"
static int CheckEqualFunc(ElementType *a, ElementType *b)
{
    return !(a->To == b->To);
}

AdjacencyList InitializeAdjacencyList(int Size)
{
    int i = 0;

    AdjacencyList H = malloc(sizeof(*H));
    if (!H)
        FatalError("Out of space");
    H->TableSize = Size;
    H->TheLists = malloc(sizeof(*H->TheLists) * Size);

    if (!H->TheLists)
        FatalError("Out of space");
    for (i = 0; i < H->TableSize; i++)
    {
        H->TheLists[i] = malloc(sizeof(*(H->TheLists[i])));
        if (!H->TheLists[i])
            FatalError("Out of space");
        H->TheLists[i]->Next = NULL;
    }
    goto _success;
_success:
    goto _exit;
_error:
    DestoryTable(H);
    H = NULL;
    goto _exit;
_exit:
    return H;
}

void DestoryTable(AdjacencyList H)
{
    int i = 0;
    List TmpL = NULL;
    Position P = NULL;
    Position TmpP = NULL;

    if (H)
    {
        if (H->TheLists)
        {
            for (i = 0; i < H->TableSize; i++)
            {
                TmpL = H->TheLists[i];
                P = TmpL->Next;
                while (P)
                {
                    TmpP = P->Next;
                    free(P);
                    P = TmpP;
                }
            }
        }
        free(H->TheLists);
        free(H);
    }
}

static Position Find(Index index, ElementType *X, AdjacencyList H)
{
    List L = NULL;
    Position P = NULL;
    L = H->TheLists[index];
    P = L->Next;
    while (P != NULL && CheckEqualFunc(X, &P->Element))
        P = P->Next;
    return P;
}

void Insert(Index index, ElementType *X, AdjacencyList H)
{
    if (!X)
        FatalError("X is NULL!");
    if (index >= H->TableSize)
        FatalError("index out of space!");

    Position P = NULL;
    List L = NULL;
    P = Find(index, X, H);
    if (!P)
    {
        P = malloc(sizeof(*P));
        if (!P)
            FatalError("Out of space");
        L = H->TheLists[index];
        P->Element.To = X->To;
        P->Element.Weight = X->Weight;

        P->Next = L->Next;
        L->Next = P;
    }
    else
    {
        P->Element.To = X->To;
        P->Element.Weight = X->Weight;
    }
}

void Print(AdjacencyList H)
{
    int i = 0;
    List TmpL = NULL;
    Position P = NULL;
    for (i = 0; i < H->TableSize; i++)
    {
        printf("From: %d\n", i);
        TmpL = H->TheLists[i];
        P = TmpL->Next;
        while (P)
        {
            printf("To: %d, Weight: %d\n", P->Element.To, P->Element.Weight);
            P = P->Next;
        }
    }
}